#pragma once

#include <cassert>
#include <cstdint>

namespace model {

template <int SZ> struct OneWire {
  static constexpr auto Size = SZ;
  using Counter = uint16_t;

  bool toggle(Counter delay) {
    assert(ptr >= 0);
    if (++counter > 0) {
      if (counter % 2 == 0) {
        if (delay > prev) {
          data[ptr] |= 1 << bit;
        }
        if (--bit < 0) {
          bit = 7;
          --ptr;
        }
      }
    }
    prev = delay;
    return (ptr < 0);
  }

  uint8_t data[SZ];
  int ptr = SZ - 1;
  int bit = 7;
  int counter = -3;
  Counter prev = 0;
};

} // namespace model
